<html><head><meta charset="utf-8"><title>使用模块封装代码-慕课专栏</title>
			<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
			<meta name="renderer" content="webkit">
			<meta property="qc:admins" content="77103107776157736375">
			<meta property="wb:webmaster" content="c4f857219bfae3cb">
			<meta http-equiv="Access-Control-Allow-Origin" content="*">
			<meta http-equiv="Cache-Control" content="no-transform ">
			<meta http-equiv="Cache-Control" content="no-siteapp">
			<link rel="apple-touch-icon" sizes="76x76" href="https://www.imooc.com/static/img/common/touch-icon-ipad.png">
			<link rel="apple-touch-icon" sizes="120x120" href="https://www.imooc.com/static/img/common/touch-icon-iphone-retina.png">
			<link rel="apple-touch-icon" sizes="152x152" href="https://www.imooc.com/static/img/common/touch-icon-ipad-retina.png">
			<link href="https://moco.imooc.com/captcha/style/captcha.min.css" rel="stylesheet">
			<link rel="stylesheet" href="https://www.imooc.com/static/moco/v1.0/dist/css/moco.min.css?t=201907021539" type="text/css">
			<link rel="stylesheet" href="https://www.imooc.com/static/lib/swiper/swiper-3.4.2.min.css?t=201907021539">
			<link rel="stylesheet" href="https://static.mukewang.com/static/css/??base.css,common/common-less.css?t=2.5,column/zhuanlanChapter-less.css?t=2.5,course/inc/course_tipoff-less.css?t=2.5?v=201907051055" type="text/css">
			<link charset="utf-8" rel="stylesheet" href="https://www.imooc.com/static/lib/ueditor/themes/imooc/css/ueditor.css?v=201907021539"><link rel="stylesheet" href="https://www.imooc.com/static/lib/baiduShare/api/css/share_style0_16.css?v=6aba13f0.css"></head>
			<body><div id="main">

<div class="container clearfix" id="top" style="display: block; width: 1134px;">
    
    <div class="center_con js-center_con l" style="width: 1134px;">
        <div class="article-con">
                            <!-- 买过的阅读 -->
                <div class="map">
                    <a href="/read" target="_blank"><i class="imv2-feather-o"></i></a>
                    <a href="/read/35" target="_blank">零基础学透 TypeScript</a>
                    <a href="" target="_blank">
                        <span>
                            / 4-1 使用模块封装代码
                        </span>
                    </a>
                </div>

            


            <div class="art-title" style="margin-top: 0px;">
                使用模块封装代码
            </div>
            <div class="art-info">
                
                <span>
                    更新时间：2019-07-09 16:32:59
                </span>
            </div>
            <div class="art-top">
                                <img src="https://img4.mukewang.com/5d244de80001b37606400359.jpg" alt="">
                                                <div class="famous-word-box">
                    <img src="https://www.imooc.com/static/img/column/bg-l.png" alt="" class="bg1 bg">
                    <img src="https://www.imooc.com/static/img/column/bg-r.png" alt="" class="bg2 bg">
                    <div class="famous-word">横眉冷对千夫指，俯首甘为孺子牛。<p class="author">——鲁迅</p></div>
                </div>
                            </div>
            <div class="art-content js-lookimg">
                <div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">TypeScript 在 1.5 版本之前，有<strong>内部模块</strong>和<strong>外部模块</strong>的概念，从 1.5 版本开始，<strong>内部模块</strong>改称作<strong>命名空间</strong>（我们下个小节会讲），<strong>外部模块</strong>改称为<strong>模块</strong>。如果你对模块的知识一无所知，建议你先重点学习一下 <code>CommonJS</code> 模块系统和 ES6模块系统，TypeScript 中的模块系统是遵循 ES6 标准的，所以你需要重点学习 ES6 标准中的模块知识，这里推荐大家几个链接，大家可以在这里去学习一下：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;"><a href="http://www.mamicode.com/info-detail-1935796.html">CommonJS/AMD/CMD/ES6规范</a></li>
<li style="font-size: 20px; line-height: 38px;"><a href="http://es6.ruanyifeng.com/#docs/module">ECMAScript6入门 - Module 的语法</a></li>
</ul>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">TypeScript 和 ES6 保持一致，包含顶级 import 或 export 的文件都被当成一个模块，则里面定义的内容仅模块内可见，而不是全局可见。TypeScript 的模块除了遵循 ES6 标准的模块语法外，还有一些特定语法，用于类型系统兼容多个模块格式，下面我们来开始学习 TypeScript 模块。</p>
</div><div class="cl-preview-section"><h3 id="export">4.1.1. export</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">TypeScript 中，仍然使用 export 来导出声明，而且能够导出的不仅有变量、函数、类，还包括 TypeScript 特有的类型别名和接口。</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// funcInterface.ts</span>
<span class="token keyword">export</span> <span class="token keyword">interface</span> <span class="token class-name">Func</span> <span class="token punctuation">{</span>
  <span class="token punctuation">(</span>arg<span class="token punctuation">:</span> <span class="token keyword">number</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">string</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">C</span> <span class="token punctuation">{</span>
  <span class="token keyword">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> B <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> B <span class="token keyword">as</span> ClassB <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">上面例子中，你可以使用 export 直接导出一个声明，也可以先声明一个类或者其它内容，然后使用 export {}的形式导出，也可以使用 as 来为导出的接口换个名字再导出一次。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">你也可以像 ES6 模块那样重新导出一个模块，也就是 export 一个引入内容，也可以重新导出部分内容，也可以重命名重新导出：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// main.ts</span>
<span class="token keyword">export</span> <span class="token operator">*</span> <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
<span class="token comment">// main.ts</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> name <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
<span class="token comment">// main.ts</span>
<span class="token keyword">export</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> nameProp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="import">4.1.2. import</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">接下来我们来看导出的模块怎么引入，依然是使用 import：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// main.ts</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
<span class="token comment">// main.ts</span>
<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> info <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
<span class="token comment">//main.ts</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> name <span class="token keyword">as</span> nameProp <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./moduleB"</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">同样，可以使用 import 直接接模块名或文件路径，进行具有副作用的导入：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token keyword">import</span> <span class="token string">"./set-title.ts"</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="export-default">4.1.3. export default</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">同样在 TypeScript 中使用 export default 默认导出，这个和 ES6 一样：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// moduleB.ts</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token string">"lison"</span><span class="token punctuation">;</span>
<span class="token comment">// main.ts</span>
<span class="token keyword">import</span> name <span class="token keyword">from</span> <span class="token string">"./moduleB.ts"</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 'lison'</span>
</code></pre>
</div><div class="cl-preview-section"><h3 id="export--和-import--require">4.1.4. export = 和 import = require()</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">TypeScript可以将代码编译为CommonJS、AMD或其它模块系统代码，同时会生成对应的声明文件。我们知道CommonJS和AMD两种模块系统语法是不兼容的，所以TypeScript为了兼容这两种语法，使得我们编译后的声明文件同时支持这两种模块系统，增加了<code>export =</code>和<code>import xx = require()</code>两个语句。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">当我们想要导出一个模块时，可以使用<code>export =</code>来导出：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// moduleC.ts</span>
<span class="token keyword">class</span> <span class="token class-name">C</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">export</span> <span class="token operator">=</span> C<span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">然后使用这个形式导出的模块，必须使用<code>import xx = require()</code>来引入：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// main.ts</span>
<span class="token keyword">import</span> ClassC <span class="token operator">=</span> <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token string">"./moduleC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> c <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ClassC</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">如果你的模块不需要同时支持这两种模块系统，可以不使用<code>export =</code>来导出内容。</p>
</div><div class="cl-preview-section"><h3 id="相对和非相对模块导入">4.1.5. 相对和非相对模块导入</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">根据引入模块的路径是相对还是非相对，模块的导入会以不同的方式解析：</p>
</div><div class="cl-preview-section"><ul>
<li style="font-size: 20px; line-height: 38px;">相对导入是以<code>./</code>或<code>…/</code>开头的，<code>./</code>表示当前目录，而<code>…/</code>表示当前目录的上一级目录。以下面的文件目录为例：</li>
</ul>
</div><div class="cl-preview-section"><pre class="  language-shell"><code class="prism  language-shell">src
 ╠═ module
 ║    ╠═ moduleA.ts
 ║    ╚═ moduleB.ts
 ╚═ core
      ╚═ index.ts
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">以上面的文件目录为例，我们如果在 index.ts 中引入两个模块，和在 moduleA 模块中引入 moduleB 是这样的：</p>
</div><div class="cl-preview-section"><pre class="  language-typescript"><code class="prism  language-typescript"><span class="token comment">// moduleA.ts</span>
<span class="token keyword">import</span> moduleB <span class="token keyword">from</span> <span class="token string">"./moduleB.ts"</span><span class="token punctuation">;</span> <span class="token comment">// 这里在moduleA.ts文件里引入同级的moduleB.ts文件，所以使用./表示moduleA.ts文件当前所在路径</span>
<span class="token comment">// index.ts</span>
<span class="token keyword">import</span> moduleA <span class="token keyword">from</span> <span class="token string">"../module/moduleA.ts"</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> moduleB <span class="token keyword">from</span> <span class="token string">"../module/moduleB"</span><span class="token punctuation">;</span> <span class="token comment">// 这里省略了.ts后缀也可以</span>
</code></pre>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">当我们引用模块文件的时候省略了 .ts 后缀也是可以的，这就涉及到一个模块解析策略。我们以上面例子中这个moduleB 为例，编译器在解析模块引用的时候，如果遇到省略后缀的情况，会依次查找以该名称为文件名的.ts、.tsx、.d.ts文件；如果没找到，会在当前文件夹下的 package.json 文件里查找 types 字段指定的模块路径，然后通过这个路径去查找模块；如果没找到package.json文件或者types字段，则会将 moduleB 当做文件夹去查找，如果它确实是文件夹，将会在这个文件夹下依次查找 index.ts、index.tsx、index.d.ts。  如果还没找到，会在上面例子中 module 文件夹的上级文件夹继续查找，查找规则和前面这些顺序一致。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">除了这两种符号开头的路径，都被当做非相对路径。非相对模块的导入可以相对于 baseUrl，也可以通过路径映射，还可以解析为外部模块。关于模块解析的更多配置，我们会在后面章节介绍，这里我们主要学习语法。</p>
</div><div class="cl-preview-section"><h3 id="小结">小结</h3>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">本小节我们学习了 TypeScript 的模块系统，使用模块我们可以将一些逻辑封装在模块中，方便在多个文件中引入使用，这样可以帮我们更方便地整理、复用代码。在这个小节中我们学习了 TypeScript 中遵循 ES6 的模块语句，其中导出语句为 <code>export</code>，引入语句为 <code>import</code>，如果要默认导出，则使用 <code>export default</code>。我们还学习了 TypeScript 中特别增加的兼容 CommonJS 和 AMD 模块系统的导出和导入语句：<code>export =</code>和<code>import xx = require()</code>。最后我们简单学习了相对模块和非相对模块的引入，同时还介绍了模块引用的解析策略。</p>
</div><div class="cl-preview-section"><p style="font-size: 20px; line-height: 38px;">下个小节我们将学习命名空间，命名空间在TypeScirpt1.5版本之前称为“内部模块”，它可以将属于一类的代码进行汇总封装，效果类似于我们这节课学习的模块，下个小节我们来进行学习。<br>
<img src="http://img.mukewang.com/5d22b95e0001a6ac16000547.jpg" alt="图片描述" data-original="http://img.mukewang.com/5d22b95e0001a6ac16000547.jpg" class="" style="cursor: pointer;"></p>
</div></div>
            </div>
                            <!-- 买过的阅读 -->
                <div class="art-next-prev clearfix">
                                                                        <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/362">
                                                    <div class="prev l clearfix">
                                <div class="icon l">
                                    <i class="imv2-arrow3_l"></i>
                                </div>
                                <p>
                                    25 入手装饰器，给凡人添加超能力
                                </p>
                            </div>
                        </a>
                                                                                            <!-- 已买且开放 或者可以试读 -->
                            <a href="/read/35/article/364">
                                                    <div class="next r clearfix">
                                <p>
                                    使用命名空间封装代码
                                </p>
                                <div class="icon r">
                                    <i class="imv2-arrow3_r"></i>
                                </div>

                            </div>
                        </a>
                                    </div>
                    </div>
        <div class="comments-con js-comments-con" id="coments_con">
        </div>



    </div>
    
    
    

</div>
 
<!-- 专栏介绍页专栏评价 -->

<!-- 专栏介绍页底部三条评价 -->

<!-- 专栏阅读页弹层目录和介绍页页面目录 -->

<!-- 专栏阅读页发布回复 -->

<!-- 专栏阅读页发布评论 -->

<!-- 专栏阅读页底部评论 -->

<!-- 专栏阅读 单个 评论 -->

<!-- 新增回复和展开三条以外回复 -->

<!-- 立即订阅的弹窗 -->












</div></body></html>